// 文件名：mdspan_image_pitch.cpp
// 目的：为“行对齐（带 pitch/stride）的图像缓冲区”建立三维视图 [rows, cols, channels]，并进行读写。
// 背景：
//   - 图像每行常需按对齐（alignment）向上取整，导致行跨度（rowStride）≥ width*channels；
//   - 使用 std::layout_stride 可为每个维度指定自定义跨距（strides），适应非连续布局。
// 关键点：
//   - rgb_view 为三维 mdspan，固定第三维为 3（RGB 通道），布局为 layout_stride；
//   - strides = {rowStride, channels, 1} 分别代表行步长、列步长、通道步长（以元素为单位）；
//   - 通过 image(y,x,c) 读写，底层按 strides 正确寻址。
// 注意：
//   - buffer 的元素类型为 uint8_t，每像素 3 通道；rowStride 以“元素数”计（此处等同于字节数）；
//   - 需确保 strides 与 extents 一致（行跨度至少覆盖一行的所有通道数据）。
#include <cstddef>
#include <iostream>
#include <mdspan>
#include <vector>

using rgb_view = std::mdspan<std::uint8_t,
                             std::extents<std::size_t,
                                          std::dynamic_extent, // rows
                                          std::dynamic_extent, // cols
                                          3>,                   // channels
                             std::layout_stride>;

int main() {
    const std::size_t width = 4;
    const std::size_t height = 3;
    const std::size_t channels = 3;
    const std::size_t alignment = 4; // 对齐到 4 字节
    const std::size_t rowStride = ((width * channels + (alignment - 1)) / alignment) * alignment;

    // 总缓冲大小 = 行数 * 行跨度
    std::vector<std::uint8_t> buffer(height * rowStride, 0);

    std::array<std::size_t, 3> strides{
        rowStride,                      // 行跨度（以元素为单位）
        channels,                       // 列跨度：相邻列相差 channels 个元素
        1                               // 通道跨度：相邻通道相差 1
    };

    rgb_view image(buffer.data(),
                   rgb_view::mapping_type(
                       std::extents<std::size_t, std::dynamic_extent, std::dynamic_extent, 3>(height, width, channels),
                       strides));

    // 设置一个简单的棋盘花纹
    for (std::size_t y = 0; y < height; ++y) {
        for (std::size_t x = 0; x < width; ++x) {
            std::uint8_t value = ((x + y) % 2 == 0) ? 255 : 32;
            image(y, x, 0) = value; // R
            image(y, x, 1) = value; // G
            image(y, x, 2) = value; // B
        }
    }

    // 打印亮度（取 R 通道）
    for (std::size_t y = 0; y < height; ++y) {
        for (std::size_t x = 0; x < width; ++x) {
            std::cout << static_cast<int>(image(y, x, 0)) << ' ';
        }
        std::cout << '\n';
    }
    return 0;
}